package gestIT;

/**
 * Subclass of TmpExp that represent a simple building block.
 * A simple building block can check a constraint, if it is constructed with an ExpContent
 * 
 * @author nicola
 *
 */
public class SimpleTmpExp extends TmpExp {

	/** The Content that will check the constraint */
	public ExpContent Content;
	/** The token of the execution */
	public Token token;
	
	/**
	 * Constructor that return a new SimpleTmpExp without ExpContent connected
	 */
	public SimpleTmpExp(){
		this.type = ExpType.Simple;
	}
	
	/**
	 * Constructor that return a new SimpleTmpExp with an ExpContent connected
	 * @param cnt The ExpContent that will check the constraint 
	 */
	public SimpleTmpExp(ExpContent cnt){
		this.Content = cnt;
	}
	
	/**
	 * Method that check if event parameters will satisfy the current simple building block
	 * @param arg The event parameter to be checked
	 * @return True if the event meet the constraint, else otherwise
	 */
	public boolean Accepts(ExpEventArgs arg){
		if (this.state != ExecState.Enabled)
			return false;
		if (Content != null)
			return Content.Accepts(arg, token);
		return false;
	}
	
	/**
	 * Method that consume an event
	 * @param arg The event parameter to be consumed
	 * @return True if the event meet has been consumed, else otherwise
	 */
	public boolean Consume(ExpEventArgs arg){
		
		if (Content != null){
			
			boolean toRet = Content.Consume(arg, token);
			if (toRet){
				this.SetExecState(ExecState.Completed, token);
				RaiseCompleted(this, arg, token);
			} else {
				this.SetExecState(ExecState.Error, token);
				RaiseError(this, arg, token);
			}
			RaiseOnStateChanged(this, arg, token);
			if (this.Iterative)
				this.SetExecState(ExecState.Enabled, token);
			
			return toRet;
		}
		return false;
	}
	
	/**
	 * Invalidate the following simple building block and set the state to error
	 * 
	 * If the current building block is flagged as iterative, it will be setted back to enable state
	 * @param arg
	 */
	public void Invalidate(ExpEventArgs arg){
		this.SetExecState(ExecState.Error, token);
		RaiseError(this, arg, token);
		RaiseOnStateChanged(this, arg, token);
		
		if (this.Iterative)
			this.SetExecState(ExecState.Enabled, token);
	}
	

	@Override
	public void SetExecState(ExecState state, Token token){
		super.SetExecState(state, token);
		
		switch (state) {
		case Completed: case Enabled: case Performing:
			this.token = token;
			break;

		default:
			break;
		}
	}
	
}
